from abc import abstractmethod
from collections import OrderedDict
import time

from shared.events import NORTH, WEST, SOUTH, EAST, ChangeDirection, ActivateTurbo

DIRECTION_KEYS = {
    'w': NORTH,
    'a': WEST,
    's': SOUTH,
    'd': EAST
}

STOP_MOTION_KEY = ' '
TURBO_KEY = 't'


class AbstractUI(object):
    def __init__(self, state):
        self.maze = state.maze
        self.state = state

        self._frame_rate = 40  # target: 40 FPS
        self._game_name = "Pymaze - DEV"

    def update(self, state):
        self.state = state
        self.maze = state.maze

    def wait(self):
        """Wait the time until next frame."""
        time.sleep(1 / self._frame_rate)

    @abstractmethod
    def terminate(self):
        """Terminate the UI."""
        pass

    def _get_event_from_char(self, char):
        """Get the movement event for the player given the input character.

        Returns None if the input character does not correspond to a movement key.
        """
        if char in DIRECTION_KEYS:
            return ChangeDirection(self.state.player, DIRECTION_KEYS[char])
        elif char == STOP_MOTION_KEY:
            return ChangeDirection(self.state.player, None)
        elif char == TURBO_KEY:
            return ActivateTurbo(self.state.player)

    def _get_key_help(self):
        dct = OrderedDict()
        for k in DIRECTION_KEYS:
            dct[k] = 'Move ' + DIRECTION_KEYS[k].name
        dct[STOP_MOTION_KEY] = 'Stop moving'
        dct[TURBO_KEY] = 'Turbo mode'

        return dct
